import { useState, useRef } from "react";
import { listen } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api";




function App() {

  // 定义textareaRef变量，使用useRef钩子函数创建，用于保存textarea元素的引用
  const textareaRef = useRef(null);

  // 定义userInput状态变量和setUserInput函数，用于保存用户输入的文本内容
  const [userInput, setUserInput] = useState('');

  // 定义mesgs状态变量和setMesgs函数，用于保存机器人和用户之间的消息记录
  const [mesgs, setMesgs] = useState([
    {
      user: "说说你都能干什么",
      robot: "反正比你知道的多！！",
    }
  ]);

  // 定义unlisten变量，用于保存停止监听的函数

  let unlisten = null;

  // 定义handleTextareaChange函数，用于处理textarea元素的值变化事件
  const handleTextareaChange = (event) => {
    setUserInput(event.target.value)
  }

  // 定义sendPost函数，用于发送消息到后端并开始监听机器人的回复
  const sendPost = () => {
    // 获取用户输入的消息
    const userMsg = userInput;

    // 清空用户输入的文本内容
    setUserInput("");

    // 判断用户是否已经输入
    if (!userMsg) {
      console.log("userInput is empty");
      return;
    }

    // 防止重复监听
    if (unlisten != null) {
      console.log("already listen");
      return;
    }

    // 标记原来的mesgs
    const orgMsgs = [...mesgs];

    // 调用后端的init_process接口，将用户输入作为参数传递
    const jsonString = JSON.stringify(orgMsgs);
    invoke("init_process", { usermsg: userMsg, memory: jsonString });

    // 定义start_listen函数，用于开始监听机器人的回复并返回一个Promise对象
    const start_listen = async (orgMsgs, userMsg) => {
      // 注意这里的my-event名称，要与后端保持一致
      // 监听botMsg事件，当机器人回复时触发回调函数
      return await listen('botMsg', (event) => {
        console.log(orgMsgs);
        console.log(userMsg);

        // 获取机器人回复的消息
        const botmsg = event.payload;

        // 判断机器人回复是否包含数据
        if (botmsg.includes('data:')) {
          // 首先去除掉data：头部字符串
          const jsonData = botmsg.replace(/^data:/, '');

          try {
            // 将其解析为json
            const jsonObject = JSON.parse(jsonData);

            // 获取文本内容
            const textValue = jsonObject.output.text;

            // 更新mesgs状态
            const newMesg = {
              user: userMsg,
              robot: textValue,
            }
            setMesgs([...orgMsgs, newMesg]);
            window.scrollTo(0, document.body.scrollHeight);

            // 获取是否成功
            var finish_reason = jsonObject.output.finish_reason;

            // 如果机器人回复完毕，停止监听
            if (finish_reason == "stop") {
              stop();
            }
          } catch (e) {
            console.error('Error parsing JSON:', e);
          }
        }
      });
    };

    // 开始监听机器人的回复
    unlisten = start_listen(orgMsgs, userMsg);

    // 定义stop函数，用于停止监听机器人的回复
    stop = () => {
      console.log("is_listening:", unlisten != null);
      if (unlisten != null) {
        unlisten.then((ok) => {
          ok();
          unlisten = null;
          console.log("stop success");
        }).catch((err) => {
          console.log("stop fail", err);
        });
      }
    }
  }




  return (
    <div className="mx-10 flex flex-col" >
      <div className="flex items-center justify-center mb-10">
        <img src="./robot.svg" alt="" className="h-8 mr-2" />
        <p className=" text-lg font-semibold ">Qwen72b</p>
      </div>

      <ul role="list" className="space-y-5 pb-40">
        {mesgs.map((msg, index) => (
          <li className=" space-y-5" key={index}>
            <div className="flex gap-x-3">
              <img src="./user.svg" className="w-5 h-5" alt="" />
              <p>
                {msg.user}
              </p>
            </div>
            <div className="flex gap-x-3">
              <img src="./robot.svg" className="w-5 h-5" alt="" />
              <p className="whitespace-pre-wrap bg-slate-300">{msg.robot}</p>
            </div>
          </li>
        ))}
      </ul>



      <div class="fixed bottom-0 left-0 right-0 p-4 bg-white">
        <div className="flex">
          <textarea value={userInput} onChange={handleTextareaChange} class="w-full border rounded px-4 py-2 max-h-36" placeholder="Type something..." />
          <div className="flex items-end justify-end"><button onClick={sendPost}>发送</button></div>
        </div>

      </div>
    </div >
  );
}

export default App;
